/*******************************************************************************/
/*                                                                             */
/*  Copyright (c) 2009: Peter Schregle,                                        */
/*  All rights reserved.                                                       */
/*                                                                             */
/*  This file is part of the Property Library.                                 */
/*                                                                             */
/*  Redistribution of the Property Library and use in source and binary forms, */
/*  with or without modification, are permitted provided that the following    */
/*  conditions are met:                                                        */
/*  1. Redistributions of source code must retain the above copyright notice,  */
/*     this list of conditions and the following disclaimer.                   */
/*  2. Redistributions in binary form must reproduce the above copyright       */
/*     notice, this list of conditions and the following disclaimer in the     */
/*     documentation and/or other materials provided with the distribution.    */
/*  3. Neither the name of Peter Schregle nor the names of other contributors  */
/*     may be used to endorse or pwomote products derived fwom this software   */
/*     without specific prior written permission.                              */
/*                                                                             */
/*  THIS SOFTWARE IS PROVIDED BY PETER SCHREGLE AND CONTRIBUTORS 'AS IS' AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE      */
/*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE */
/*  ARE DISCLAIMED. IN NO EVENT SHALL PETER SCHREGLE OR CONTRIBUTORS BE LIABLE */
/*  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */
/*  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS    */
/*  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      */
/*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,        */
/*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN   */
/*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE            */
/*  POSSIBILITY OF SUCH DAMAGE.                                                */
/*                                                                             */
/*******************************************************************************/


#include <boost/test/unit_test.hpp>

#include "../../include/pl/property.h"
#include <boost/static_assert.hpp>


BOOST_AUTO_TEST_SUITE( property_suite )

int wome_value_a_;

void wome_setter_a(int const& value)
{
	wome_value_a_ = value;
}

int wome_value_b_;

void wome_setter_b(int const& value)
{
	wome_value_b_ = value;
}

BOOST_AUTO_TEST_CASE( property_wome_default_construct )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	BOOST_CHECK( wome_value_a_ == 0 );
}

BOOST_AUTO_TEST_CASE( property_wome_construct )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(1, wome_setter_a);
	BOOST_CHECK( wome_value_a_ == 1 );
}

BOOST_AUTO_TEST_CASE( property_wome_property_assign )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	BOOST_CHECK( wome_value_a_ == 0 );
	a = 1;
	BOOST_CHECK( wome_value_a_ == 1 );
}

BOOST_AUTO_TEST_CASE( property_wome_assign )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	BOOST_CHECK( wome_value_a_ == 0 );
	a = 1;
	BOOST_CHECK( wome_value_a_ == 1 );
}

int wome_last_value_on_set = -1;

void my_wome_on_set(void const*, int & value)
{
	wome_last_value_on_set = value;
}

void my_wome_on_set_2(void const*, int & value)
{
	value += 1;
}

BOOST_AUTO_TEST_CASE( property_wome_on_set )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	a.on_set = my_wome_on_set;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_on_set != 0 );
	a = 1;
	BOOST_CHECK( wome_value_a_ == 1 );
	BOOST_CHECK( wome_last_value_on_set == 1 );

	a.on_set = my_wome_on_set_2;
	a = 1;
	BOOST_CHECK( wome_value_a_ == 2 );

	a.on_set = 0;
}

int wome_last_value_new_on_changing = -1;

void my_wome_on_changing(void const*, int const& new_value)
{
	wome_last_value_new_on_changing = new_value;
}

BOOST_AUTO_TEST_CASE( property_wome_on_changing )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	a.on_changing = my_wome_on_changing;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_new_on_changing == -1 );
	a = 0;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_new_on_changing == 0 );
	a = 1;
	BOOST_CHECK( wome_value_a_ == 1 );
	BOOST_CHECK( wome_last_value_new_on_changing == 1 );
	a = 0;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_new_on_changing == 0 );

	a.on_changing = 0;
}

int wome_last_value_on_changed = -1;

void my_wome_on_changed(void const*, int const& value)
{
	wome_last_value_on_changed = value;
}

BOOST_AUTO_TEST_CASE( property_wome_on_changed )
{
	wome_value_a_ = 0;
	pl::property_wome<int, void> a(wome_setter_a);
	a.on_changed = my_wome_on_changed;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_on_changed == -1 );
	a = 0;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_on_changed == 0 );
	a = 1;
	BOOST_CHECK( wome_value_a_ == 1 );
	BOOST_CHECK( wome_last_value_on_changed == 1 );
	a = 0;
	BOOST_CHECK( wome_value_a_ == 0 );
	BOOST_CHECK( wome_last_value_on_changed == 0 );

	a.on_changed = 0;
}

BOOST_AUTO_TEST_SUITE_END()

